home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
cmln0286.arc
/
EXOTIC1.CUT
< prev
next >
Wrap
Text File
|
1986-02-03
|
5KB
|
112 lines
Sample Program #2
From: Exotic Language on RATFOR
February 1986
subroutine gaujor(a,n,detmt) #Gauss-Jordan matrix inversion with pivoting
# Number of operations is n**2*(n-1) multiplies and n**2 divides
# Reference: Bauer, F. L. and Reinsch, C., "Inversion of Positive Definite
# Matrices by the Gauss-Jordan Method", given as pp 45-49 of
# Hanbook for Automatic Computation, J. H. Wilkinson and C. Reinsch, Eds.,
# Springer-Verlag, 1971. The general case of Gauss-Jordan reduction
# is given on page 45. Each Gauss-Jordan reduction is done by finding
# the largest element in the matrix which does not correspond to a reduced
# element. This is the pivot element. The operation of Gauss-Jordan
# reduction is solving for the element corresponding to the pivot column,
# then substituting for that row. Gauss-Jordan reduction interchanges
# the rows AND columns corresponding to the pivot element. As a result,
# both the rows and columns have to be interchanged to preserve matrix
# indexing. The rows are switched during computation and the columns
# are switched afterward to simplify the algorithm. The determinant is
# computed as the product of the pivot elements because the process is
# equivalent to diagonalization by Gaussian elimination (see "A First
# Course in Numerical Analysis", A. Ralston, McGraw-Hill (1965), p 400).
# Inputs:
# A(n,n)--square matrix of real elements
# n--dimension of A, limited to 30 by dimension statement
# Outputs:
# A(n,n)--inverse overstores input matrix
# detmt--determinant of input matrix
dimension a(n,n),icused(30),ipivot(30,2)
integer pvtrow,pvtcol
detmt=1.
do i=1,n #Reset "column used" flags
icused(i)=0
do level=1,n #Level=no. of rows reduced
{
temp=-1. #Find largest element in matrix for pivot
do i=1,n
{
if(icused(i)!=0) next #Skip columns if already used
do j=1,n
{
if(icused(j)!=0) next #Skip rows if already used
test=abs(a(i,j)) #Use dabs in double precision versions
if(test>temp)
{
temp=test
pvtrow=i
pvtcol=j
}
}
}
pivot=a(pvtrow,pvtcol) #Save pivot element as scalar
detmt=detmt*pivot #Update determinant
if(temp==0.) #Error exit on singular matrixè {
irank=level-1
write(3,3000) n,irank
3000 format(' ***Singular matrix in GAUJOR, order',i3,', rank',i3)
return #Zero detmt is error flag for calling routine
}
icused(pvtcol)=1 #Set "column used" flag
if(pvtrow!=pvtcol) #Swap rows (if necessary) to put
{ # pivot element on diagonal
detmt=-detmt #If rows are switched, toggle sign of detmt
do j=1,n
{
temp=a(pvtrow,j)
a(pvtrow,j)=a(pvtcol,j)
a(pvtcol,j)=temp
}
}
ipivot(level,1)=pvtrow #Save indices of switched rows & cols
ipivot(level,2)=pvtcol # for column switching operation
#Solve row pvtcol of y=A*x for x(pvtcol) and replace that row of A with
# the result. Then, replace x(pvtcol) in the rest of the rows by
# substitution from the same result. After doing this for all rows,
# the result is x=A^(-1)*y, and A has been replaced by A^(-1).
#The signs of x(pvtcol) and y(pvtcol) are reversed to simplify the code.
#The equation for row pvtcol is (using p in lieu of pvtcol for brevity):
# x(p)=[sum(j=1,n;j!=p) (a(p,j)/a(p,p))*x(j)]+(1/a(p,p))*y(p)
#The equation for the other rows is:
# y(i)=[sum(j=1,n;j!=p) (a(i,j)-(a(i,p)*a(p,j)/a(p,p)))*x(i)]
# -(a(i,p)/a(p,p))*y(p)
#Do the reduced row first to provide a(p,j)/a(p,p) for reducing other rows
a(pvtcol,pvtcol)=1. #Diagonal element is special case
do j=1,n #Divide rest of reduced row by diagonal element
a(pvtcol,j)=a(pvtcol,j)/pivot
do i=1,n #Account for substituting x(pvtcol)
{ # into other rows
if(i==pvtcol) next #Reduced row was done first
temp=a(i,pvtcol) #Column for x(pvtcol) is used in whole row
a(i,pvtcol)=0. #Accout for x(pvtcol) moved to left side
do j=1,n #Special case j=pvtcol OK
a(i,j)=a(i,j)-a(pvtcol,j)*temp
}
}
for(level=n;level>0;level=level-1)
{ #Inversion complete--interchange columns
j1=ipivot(level,1) # corresponding to pivoted rows to
j2=ipivot(level,2) # restore matrix indexing
if(j1==j2) next #Skip "do nothing" swaps
do i=1,n
{
temp=a(i,j1)
a(i,j1)=a(i,j2)
a(i,j2)=temp
}
}
returnèend